package bridge

import "fmt"

type MessageImpl interface {
	send(text, to string)
}

type MessageSMS struct {
}

type MessageEmail struct {
}

func (ms *MessageSMS) send(text, to string) {
	fmt.Printf("SMS: send [%v] to [%v]\n", text, to)
}

func (me *MessageEmail) send(text, to string) {
	fmt.Printf("Email: send [%v] to [%v]\n", text, to)
}

func ViaSMS() *MessageSMS {
	return &MessageSMS{}
}

func ViaEmail() *MessageEmail {
	return &MessageEmail{}
}

type AbstractMessage interface {
	SendMessage(text, to string)
}

type CommonMessage struct {
	method MessageImpl
}

// SendMessage in this way, abstract and implement is split
func (c *CommonMessage) SendMessage(text, to string) {
	c.method.send(text, to)
}

func NewCommonMessage(mi MessageImpl) *CommonMessage {
	return &CommonMessage{method: mi}
}

type UrgencyMessage struct {
	method MessageImpl
}

func (u *UrgencyMessage) SendMessage(text, to string) {
	u.method.send(fmt.Sprintf("[Urgency Message]: %v", text), to)
}

func NewUrgencyMessage(mi MessageImpl) *UrgencyMessage {
	return &UrgencyMessage{method: mi}
}
